import 'dart:async';

import 'package:flutter/material.dart';

class CommonButton extends StatelessWidget {
  final String text;
  final Color? textColor;
  final double? fontSize;
  final Color? disableTextColor;
  final Color? backgroundColor;
  final Color? pressedColor;
  final Color? disableBackgroundColor;
  final double borderRadius;
  final BorderSide borderSide;
  final Size? size;
  final EdgeInsetsGeometry? padding;
  final double? elevation;
  final bool isEnable;
  final bool isDisableRipple;
  final MaterialTapTargetSize tapTargetSize;
  final Gradient? gradient;
  final VoidCallback? onPressed;

  const CommonButton(
    this.text,{
    super.key,
    this.textColor,
    this.fontSize,
    this.disableTextColor,
    this.backgroundColor,
    this.pressedColor,
    this.disableBackgroundColor,
    this.borderRadius = 4.0,
    this.borderSide = const BorderSide(color: Colors.transparent),
    this.size,
    this.padding,
    this.elevation,
    this.isEnable = true,
    this.isDisableRipple = false,
    this.tapTargetSize = MaterialTapTargetSize.shrinkWrap,
    this.gradient,
    this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    var button = ElevatedButton(
      key: key,
      onPressed: isEnable ? onPressed : null,
      style: ButtonStyle(
        splashFactory: isDisableRipple ? NoSplash.splashFactory : null,
        backgroundColor: WidgetStateProperty.resolveWith((states) {
          /// if set gradient, disable button backgroundColor.
          if (gradient != null) {
            return Colors.transparent;
          }
          if (states.contains(WidgetState.disabled)) {
            return disableBackgroundColor;
          }
          if (states.contains(WidgetState.pressed)) return pressedColor;
          return backgroundColor;
        }),
        textStyle: WidgetStateProperty.resolveWith((states) {
          return TextStyle(fontSize: fontSize);
        }),
        foregroundColor: WidgetStateProperty.resolveWith((states) {
          if (states.contains(WidgetState.disabled)) return disableTextColor;
          return textColor;
        }),
        shape: WidgetStateProperty.all(RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(borderRadius),
          side: borderSide,
        )),
        minimumSize: ButtonStyleButton.allOrNull<Size>(size),
        padding: ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(padding),
        elevation: WidgetStateProperty.all(elevation),
        tapTargetSize: tapTargetSize,
      ),
      child: Text(text),
    );
    if (gradient != null) {
      return Container(
        decoration: BoxDecoration(
          gradient: gradient,
          borderRadius: BorderRadius.circular(borderRadius),
        ),
        child: button,
      );
    }
    return button;
  }
}

enum CountdownButtonState { normal, sending, countdown, end }

class CountdownButton extends StatefulWidget {
  final Duration countdownDuration;
  final String normalText;
  final String sendingText;
  final String countdownText;
  final String endText;
  final CountdownButtonState state;
  final VoidCallback onPressed;
  final VoidCallback onEnd;
  final double width;
  final double height;
  final EdgeInsets padding;

  const CountdownButton({
    super.key,
    this.countdownDuration = const Duration(seconds: 60),
    this.normalText = "send",
    this.sendingText = "sending",
    this.countdownText = "retry",
    this.endText = "send again",
    this.width = 100,
    this.height = 0,
    this.padding = const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
    required this.state,
    required this.onPressed,
    required this.onEnd,
  });

  @override
  State<CountdownButton> createState() => _CountdownButtonState();
}

class _CountdownButtonState extends State<CountdownButton> {
  Timer? _timer;
  var _currContent = "";
  var _isEnable = true;

  @override
  void initState() {
    super.initState();
    _currContent = widget.normalText;
  }

  @override
  void dispose() {
    super.dispose();
    _timer?.cancel();
  }

  @override
  void didUpdateWidget(covariant CountdownButton oldWidget) {
    super.didUpdateWidget(oldWidget);
    debugPrint("didUpdateWidget 配置更新...${widget.state.name}");
    switch (widget.state) {
      case CountdownButtonState.normal:
        _isEnable = true;
        _currContent = widget.normalText;
        break;
      case CountdownButtonState.sending:
        debugPrint("didUpdateWidget 配置是sending...");
        _isEnable = false;
        _currContent = widget.sendingText;
        break;
      case CountdownButtonState.countdown:
        debugPrint("didUpdateWidget 配置是countdown...");
        _isEnable = false;
        countdown();
        break;
      case CountdownButtonState.end:
        debugPrint("didUpdateWidget 结束...");
        _isEnable = true;
        _currContent = widget.endText;
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (ctx, constraints) {
      return ElevatedButton(
        onPressed: _isEnable
            ? () {
          widget.onPressed();
        }
            : null,
        style: ButtonStyle(
          padding: ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(
              const EdgeInsets.symmetric()),
          minimumSize: ButtonStyleButton.allOrNull<Size>(
              Size(widget.width, widget.height)),
        ),
        child: Text(_currContent),
      );
    });
  }

  countdown() {
    _timer = Timer.periodic(const Duration(seconds: 1), (t) {
      debugPrint("循环开始...${t.tick}");
      if (widget.countdownDuration.inSeconds - t.tick > 0) {
        setState(() {
          _currContent = "${widget.countdownText}:${widget.countdownDuration.inSeconds - t.tick}s";
        });
      } else {
        debugPrint("循环结束");
        t.cancel();
        widget.onEnd();
      }
    });
  }
}
